package cn.itcast.mq.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 实现ApplicationContextAware
 * 当spring bean工厂创建完后回通知setApplicationContext
 */
@Configuration
@Slf4j
public class CommonConfig implements ApplicationContextAware {

    /**
     * bean创建完时的通知调用
     * 由于ReturnCallback全局只能存在一个，所以我们在bean创建完成时声明一个
     *
     * @param applicationContext the ApplicationContext object to be used by this object
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //获取rabbitTemplate
        RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class);
        //设置ReturnCallback（消息路由到队列失败后的处理）
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            /**
             * 消息路由到队列失败的通知
             * @param message 消息
             * @param replayCode 状态码
             * @param replayText 失败的原因
             * @param exchange 投递到到交换机
             * @param routingKey 投递到路由key
             */
            @Override
            public void returnedMessage(Message message, int replayCode, String replayText, String exchange, String routingKey) {
                //由于延迟交换机插件会延迟投递到消息队列，所以发布者会收到消息投送到队列失败，在这里判断一下，如果是延迟消息，就不做处理了
                if (message.getMessageProperties().getReceivedDelay()>0){
                    return;
                }
                log.info("消息发送失败，应答码{},原因{},交换机{},路由键{},消息{}", replayCode, replayText, exchange, routingKey, message);
            }
        });
    }
}
